package net.gazhi.delonix.grac.init;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import net.gazhi.delonix.core.dao.Dao;
import net.gazhi.delonix.core.init.InitService;
import net.gazhi.delonix.core.web.RequestMappingHandlerMappingHolder;
import net.gazhi.delonix.grac.AC_TB;
import net.gazhi.delonix.grac.entity.act.Action;
import net.gazhi.delonix.grac.entity.act.MenuItem;
import net.gazhi.delonix.grac.service.ActionService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;

/**
 * 初始化菜单配置
 * 
 * @author Jeffrey Lin
 */
public class InitMenuService implements InitService {

	private static final Log logger = LogFactory.getLog(InitMenuService.class);

	@Autowired
	private RequestMappingHandlerMappingHolder mpHolder;

	@Autowired
	private ActionService actionService;

	@Autowired
	private Dao dao;

	private String[] xmlFiles;

	public void setXmlFiles(String[] xmlFiles) {
		this.xmlFiles = xmlFiles;
	}

	@Override
	public void init() throws Exception {

		logger.info("正在初始化 [Menu]...");

		List<MenuItem> items = new ArrayList<MenuItem>();
		SAXReader saxReader = new SAXReader();
		for (String xmlFile : xmlFiles) {
			logger.info("正在初始化 [Menu] 文件：" + xmlFile);
			Document document = saxReader.read(new File(Thread.currentThread().getContextClassLoader().getResource(xmlFile).getFile()));
			Element menu = document.getRootElement();
			String menuName = menu.attributeValue("name");
			items.addAll(parseChildMenuItems(null, menu, menuName));
		}
		dao.createSQLQuery("truncate table " + AC_TB.ac_menu_item).executeUpdate();
		dao.saveAll(items);
		dao.flushSession();

		logger.info("初始化 [Menu] 完成。");
	}

	private List<MenuItem> parseChildMenuItems(MenuItem parent, Element parentElement, String menuName) {
		List<MenuItem> menuItems = new LinkedList<MenuItem>();
		Iterator<?> iterator = parentElement.elementIterator();
		while (iterator.hasNext()) {
			// 读取 XML 元素属性
			Element element = (Element) iterator.next();
			String nameEn = element.attributeValue("nameEn");
			String nameZh = element.attributeValue("nameZh");
			String href = element.attributeValue("href");
			String target = element.attributeValue("target");
			String onclick = element.attributeValue("onclick");
			String method = element.attributeValue("method");

			// 根据 href 或 method 计算 action
			Action action = null;
			if (!StringUtils.hasText(method) && StringUtils.hasText(href)) {
				HandlerMethod hm = mpHolder.machMethod(href);
				if (hm == null) {
					throw new RuntimeException("菜单配置错误：没有加入 MVC 映射 " + href);
				}
				method = hm.getMethod().getDeclaringClass().getName() + "." + hm.getMethod().getName();
			}
			if (StringUtils.hasText(method)) {
				action = actionService.get(ActionService.generateActionId(method));
				if (action == null) {
					throw new RuntimeException("菜单配置错误：Action 没有持久化到数据库 " + method);
				}
			}

			MenuItem menuItem = new MenuItem(menuName, parent, nameEn, nameZh, href, target, onclick, action);
			menuItems.add(menuItem);
			menuItems.addAll(this.parseChildMenuItems(menuItem, element, menuName));
		}
		return menuItems;
	}
}
